/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MetricsRetriever.RetrieverComponents;

import DataStructures.Bug;
import java.text.ParseException;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import DataStructures.BugData;
import General.RequestMaker;
import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.w3c.dom.NodeList;

/**
 *
 * @author Manuel
 */
public class SFBugManager extends BugManager{


    private String bugLink;
    private Document document;
    private BugData data;

    public SFBugManager(String link){
        bugLink = link;
    }

    public BugData getAllBugData() {
        int lastNumber = -1;
        data = new BugData();
        String xml = "";
        String url = "";
        while(data.getNumber() % 100 == 0 && lastNumber != data.getNumber()){
            lastNumber = data.getNumber();
            url = bugLink.substring(0,bugLink.lastIndexOf("/"))+"/offset/"+lastNumber+bugLink.substring(bugLink.lastIndexOf("/"));
            if(lastNumber == 0)
                url = bugLink;
            xml = RequestMaker.getPage(url);
            if(xml.contains(url))
                this.parse(xml);
        }
        return data;
    }

    private void parse(String xmlData){
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(new ByteArrayInputStream(xmlData.getBytes()));
            traverse(document.getDocumentElement(), 0);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("Could not parse the XML String");
        }
        /*for (int i = 0;i<data.getNumber();i++){
            Bug bug = data.getBug(i);
            System.out.println("\n\nBug "+bug.getIssueID()+"\nTitle:"+bug.getTitle()+"\nDescr:"+bug.getDescription()+"\nOwner:"+bug.getOwner()+"\nStatus:"+bug.getStatus()+"\nCreated:"+bug.getCreationDate()+"\nClosed:"+bug.getSolvedDate()+"\nAuthor:"+bug.getAuthor());
        }*/
    }

    private void traverse(Node n, int level) {

        int i;
        // find out what type of node this is and call the corresponding method

        short t = n.getNodeType();
        if (t == Document.ELEMENT_NODE) {
            if(n.getNodeName().toLowerCase().equals("item")){
                this.handleItem(n);
            }

            NodeList nl = n.getChildNodes();
            if (nl.getLength() == 0) {
                return;
            }

            for (i = 0; i < nl.getLength(); i++) {
                traverse(nl.item(i), level + 1);
            }
        }
        if (t == Document.ELEMENT_NODE) {
            //END NODE
        }
    }

    private void handleItem(Node itemNode){
        Bug currentBug = new Bug();
        NodeList nl = itemNode.getChildNodes();

        for (int i = 0; i < nl.getLength(); i++) {
            Node currentNode = nl.item(i);

            //parse the description (= title)
            if(currentNode.getNodeName().equals("title")){
                String description = this.handleCDATA(currentNode);
                String id = description.substring(0,description.indexOf(" -"));
                description = description.substring(description.indexOf("- ")+2);

                currentBug.setTitle(description);
                currentBug.setIssueID(id.replaceAll(" ", ""));
            }

            //parse the author
            else if(currentNode.getNodeName().equals("author")){
                String author = currentNode.getTextContent();
                if(author != null && author.equals("nobody@users.sourceforge.net"))
                    author = null;
                if(author != null)
                    currentBug.setAuthor(author);
            }

            //parse the creation date
            else if(currentNode.getNodeName().toLowerCase().equals("pubdate")){
                try {
                    String date = currentNode.getTextContent();
                    SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
                    Date lineDate = formatter.parse(date);
                    currentBug.setCreationDate(lineDate);
                } catch (ParseException ex) {}
            }

            //parse content along with many properties
            else if(currentNode.getNodeName().toLowerCase().contains("content")){
                String content = this.handleCDATA(currentNode).toLowerCase();
                int startStatus = content.indexOf("status: ")+"status: ".length();
                int endStatus = content.indexOf("<br />",startStatus);
                currentBug.setStatus(content.substring(startStatus,endStatus));
                if(currentBug.getStatus().equals("deleted"))
                    currentBug.setStatus("closed");
                currentBug.setDescription(content.substring(content.lastIndexOf("<br />")+6));
            }
            
            //parse the link, go and catch the resolution and the owner from html
            else if(currentNode.getNodeName().toLowerCase().contains("link")){
                String link = currentNode.getTextContent().replace("&amp;", "&");
                String page = RequestMaker.getPage(link);
                int startIndex = page.indexOf("<p>", page.indexOf("<label>Resolution:</label>")) + 3;
                int endIndex = page.indexOf("</p>",startIndex);

                //if we have got that information, add the resolution
                if(!page.isEmpty() && !(startIndex < 0) && !(endIndex < 0)){
                    String resolution = page.substring(startIndex,endIndex).replaceAll(" ", "").toLowerCase();
                    currentBug.setResolution(resolution);
                }
                else
                    currentBug.setResolution(null);


                int startOwner = page.indexOf("<p>",page.indexOf("<label>Assigned:</label>")) + 3;
                int endOwner = page.indexOf("</p>",startOwner);

                //if we have got that information, add the owner
                if(!page.isEmpty() && !(startIndex < 0) && !(endIndex < 0)){
                    String owner = page.substring(startOwner,endOwner);
                    if((owner != null) && !owner.isEmpty() && !owner.toLowerCase().equals("nobody/anonymous"))
                        currentBug.setOwner(owner);
                }
            }

        }
        data.addBug(currentBug);
    }

    private String handleCDATA(Node currentNode) {
        Node childNode = currentNode.getFirstChild();
        if(childNode.getNodeType() == Document.CDATA_SECTION_NODE)
            return childNode.getNodeValue();
        else return "";
    }



}
